<template>
  <div class="employee-wrap">
    <!-- css命名的规范，我们这里用的是： 结构化的命名， 还有一种是语义化 -->
    <div class="left">
      <div>
        <span id="main">测试异步 更新的原理  {{ count }}</span>
        <button @click="updateCount">更新数据</button>
      </div>
      <div style="margin-bottom: 10px">
        <el-input
          :value="query.keyword"
          placeholder="请输入内容"
          prefix-icon="el-icon-search"
          @input="keywordChange"
        />
        <!-- v-model="query.keyword" 拆开来写 -->
        <!-- @input="query.keyword = $event" -->
      </div>
      <el-tree ref="treeRef" :data="departmentList" :props="defaultProps" default-expand-all highlight-current :expand-on-click-node="false" node-key="id" @node-click="nodeClick" />
    </div>
    <div class="right">
      <div class="top">
        <el-button v-permission="'add'" type="primary" size="small" @click="addEmployee">添加员工</el-button>
        <el-button v-permission="'import'" size="small" @click="importExcelBtn">excel导入</el-button>
        <el-button v-permission="'export'" size="small" @click="exportExcel">excel导出</el-button>
      </div>
      <el-table
        :data="employeeList"
      >
        <el-table-column
          type="selection"
          width="55"
        />
        <el-table-column
          label="头像"
          width="180"
        >
          <template v-slot="{ row }">
            <img v-if="row.staffPhoto" :src="row.staffPhoto" width="90" alt="">
            <div v-else class="staff-photo">{{ row.username?.charAt(0) }}</div>
          </template>
        </el-table-column>
        <el-table-column
          prop="username"
          label="姓名"
          width="180"
        />
        <el-table-column
          prop="mobile"
          label="手机号"
          width="180"
        />
        <el-table-column
          prop="workNumber"
          label="工号"
          width="180"
        />
        <el-table-column
          prop="username"
          label="聘用形式"
          width="180"
        >
          <template v-slot="{ row }">
            {{ row.formOfEmployment === 1 ? '正式员工' : '非正式员工' }}
          </template>
        </el-table-column>
        <el-table-column
          prop="departmentName"
          label="部门"
          width="180"
        />
        <el-table-column
          prop="timeOfEntry"
          label="入职时间"
          width="180"
        />
        <el-table-column
          label="操作"
          fixed="right"
          width="200"
        >
          <template slot-scope="{ row }">
            <!-- <router-link></router-link> -->
            <el-button type="text" @click="viewDetail(row.id)">查看</el-button>
            <el-button type="text" @click="assignRole(row.id)">角色</el-button>
            <el-button type="text" @click="deleteEmployee(row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        :current-page="query.page"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="query.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 封装的导入excel组件 -->
    <!-- <ImprotExcel :visible="visible" @xxxxx="visible = $event" /> -->
    <ImprotExcel v-model="visible" @IMPORT_SUCCESS="getUserList" />

    <!-- 下面是分配角色的弹出框 -->
    <AssignRole v-if="value" :id="id" v-model="value" />
  </div>
</template>

<script>
import { departmentRequest } from '@/api/department'
import { transfromListToTree } from '@/utils'
import { getUserListRequest, exportExcelRequest, deleteEmployeeRequest } from '@/api/employee'
import lodash from 'lodash'
// import _ from 'lodash'
// import { debounce } from 'lodash'
import FaveSaver from 'file-saver'
import ImprotExcel from './components/import-excel.vue'
import AssignRole from './components/AssignRole.vue'

// heima95-1305752761
// ap-nanjing
// id: AKIDMZwICyXq7ScZVIrAUqCLFxmV1JQK0Sgg
// key: yjDSRAdzT3b2HI8sQlslPp3D8d6OexFc

export default {
  name: 'EmployeeCom',
  components: { ImprotExcel, AssignRole },
  data() {
    return {
      count: 10,
      departmentList: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      employeeList: [],
      total: 0,
      query: {
        page: 1,
        pagesize: 10,
        keyword: '',
        deparmentId: ''
      },
      visible: false,
      value: false,
      id: 0
    }
  },
  watch: {
    'query.keyword': lodash.debounce(function(newVal) {
      this.query.page = 1
      this.getUserList()
    }, 300)
  },
  created() {
    this.department()
    // this.getUserList()

    // 工作里面协防抖函数，先去百度找demo
    // this.keywordChange = lodash.debounce(this.keywordChange, 300)
  },
  methods: {
    updateCount() {
      // 下面这句话有两个作用： 1. 将js的数据修改  2. 异步更新dom
      // 下面数据更新多次，dom执行更新一次，这也是为什么vue将dom更新写成异步的原因。 优化性能
      this.count++
      this.count++
      this.count++
      this.count++
      // 下面的打印值和this.count的值对不上。 因为下面的代码是同步的，直接打印dom上面的值。 但是dom更新是异步的
      // 页面11这个数字还没有更新完毕到新dom上面，我们就打印了这个值，所以获取的是旧的dom的值。
      console.log('旧：', document.querySelector('#main').innerHTML)
      // 如果要获取最新的dom的值，那么就需要写一个$nextTick函数或者定时器。也写一个异步任务，等同步任务执行完毕在来执行异步任务
      // this.$nextTick(() => {
      //   // 这个函数里面的代码，就是异步代码，会等上面的 “更新dom" 这个任务完成以后，在打印dom的值，这个时候就是最新的dom
      //   console.log('新：', document.querySelector('#main').innerHTML)
      // })
      // $nextTick内部的原理，是通过promise.then 还有一些其他的异步方法实现的，如果当前代码环境不支持，就是用setTimeout(fn, 0) 代替
      setTimeout(() => {
        console.log('新：', document.querySelector('#main').innerHTML)
      }, 0)

      // 以前有个面试题的答案：
      //  js里面有哪些异步任务： 定时器 dom事件  ajax +  还有vue里面的dom更新 是异步
    },
    async department() {
      const res = await departmentRequest()
      // 下面这句话，即可以将js里面的数据修改，也可以同步将页面更新。但是dom更新是异步的
      this.departmentList = transfromListToTree(res.data, 0)
      // 树形组件渲染完毕以后，紧接着将当前行高亮。根据默认的第一个id高亮
      this.query.deparmentId = this.departmentList[0].id
      this.$nextTick(() => {
        // 等dom渲染完毕以后，在执行树形组件第一行的高亮，
        // 等待当前的dom页面渲染完毕，树形组件出来了以后，再去高亮第一个元素
        this.$refs.treeRef.setCurrentKey(this.query.deparmentId)
      })

      // 这个请求一定要等depargetment这个请求结束完毕，得到了id才能发下一个请求，不能并发
      this.getUserList()
    },
    async getUserList() {
      const res = await getUserListRequest(this.query)
      this.employeeList = res.data.rows
      this.total = res.data.total
    },
    handleCurrentChange(value) {
      this.query.page = value
      this.getUserList()
    },
    handleSizeChange(value) {
      this.query.pagesize = value
      this.getUserList()
    },
    nodeClick(item, node, com) {
      this.query.deparmentId = item.id
      // 在发请求之前，一定要将页码值修改为1
      this.query.page = 1
      this.query.pagesize = 10
      this.getUserList()
    },
    // 防抖： 单位时间内只执行最后一次
    // 节流： 单位时间内只执行一次
    keywordChange(e) {
      this.query.keyword = e
      // this.query.page = 1
      // console.log(e)
      // const ss = lodash.debounce(this.getUserList, 800)
      // ss()
    },
    async exportExcel() {
      const res = await exportExcelRequest()
      console.log(res)
      // yarn add file-saver 下载一个包， 专门将二进制的流转换为 具体文件
      FaveSaver.saveAs(res, '员工信息.xlsx')
    },
    importExcelBtn() {
      this.visible = true
    },
    // 这个函数是 删除员工的意思， 涉及到的文件有 employee.vue  api/employee.js
    // 删除元素以后， 关闭弹出框，以及刷新页面
    async deleteEmployee(id) {
      await deleteEmployeeRequest(id)
      this.$message({
        message: '删除成功',
        type: 'success'
      })
      // 场景： 在当前一页，只有一个数据，这个时候点击删除， 就要主动去请求上一页的数据，页码值回到上一页
      if (this.query.page > 1 && this.employeeList.length === 1) {
        this.query.page--
      }

      this.getUserList()
    },
    // 下面去的路由既可以去 编辑页面，也叫查询页面
    viewDetail(id) {
      // 跳转到详情页面
      this.$router.push(`/employee/detail/${id}`)
    },
    // 下面的路由是去新增页面
    addEmployee() {
      this.$router.push(`/employee/detail`)
    },
    assignRole(id) {
      this.id = id
      this.value = true
    }
  }
}
</script>

<style lang="scss" scoped>
.employee-wrap {
  display: flex;
  .left {
    flex: 0 0 300px;
    // background-color: lightblue;
    // height: 500px;
    border-right: 1px solid #e8e6e6;
    padding: 15px;
  }
  .right {
    flex: 1 1 0%;
    // background-color: lightgray;
    // height: 500px;
    padding: 15px;
    overflow-x: auto;
    .top {
      text-align: right;
    }
    .staff-photo {
      width: 45px;
      height: 45px;
      background: lightblue;
      color: white;
      font-size: 20px;
      text-align: center;
      line-height: 45px;
      border-radius: 50%;
    }
  }
  .el-table {
    margin: 15px 0;
  }
  .el-pagination {
    text-align: right;
  }
}
</style>
